package cn.js189.uqc.service.impl;

import cn.js189.common.constants.BSSUrlConstants;
import cn.js189.common.constants.ExpConstant;
import cn.js189.common.domain.RespHead;
import cn.js189.common.domain.RespInfo;
import cn.js189.common.util.MainUtils;
import cn.js189.common.util.Utils;
import cn.js189.common.util.exception.BaseAppException;
import cn.js189.common.util.helper.UUIDHelper;
import cn.js189.uqc.redis.RedisOperation;
import cn.js189.uqc.service.IBssSystemService;
import cn.js189.uqc.service.IQueryConsistenceService;
import cn.js189.uqc.util.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @Author yxl
 * @Date 2024/3/6
 */
@Service
public class IQueryConsistenceServiceImpl implements IQueryConsistenceService {

    @Autowired
    private BSService bsService;

    @Resource
    private RedisOperation redisOperation;

    @Autowired
    public IBssSystemService bssSystemImpl;

    private static final Logger logger = LoggerFactory.getLogger(IQueryConsistenceServiceImpl.class);


    @Override
    public JSONObject callAcctItemConsumqr(JSONObject requestJsonParam) {
        JSONObject  requestJSON ;
	    requestJSON = EuaCacheUtil.transferParamForConsistence(requestJsonParam);
	    // 入参判空校验
        JSONObject jo = validate(requestJSON);
        if(null != jo) {
            return jo;
        }
        logger.debug("callAcctItemConsumqr(本月消费查询) input :" + requestJSON.toString());

        String areaCode = requestJSON.getString("areaCode");
        String tranId = UUIDHelper.currentTimeStampString() + "000000";
        return this.bsService.callAcctItemConsumqrNew(requestJSON, tranId, areaCode);
    }

    @Override
    public JSONObject callConQueryBalance(JSONObject requestJsonParam) {

        JSONObject  requestJSON ;
	    requestJSON = EuaCacheUtil.transferParamForConsistence(requestJsonParam);
	    
	    // 入参判空校验
        JSONObject jo = validate(requestJSON);
        if(null != jo) {
            return jo;
        }
        return this.bsService.callConQueryBalanceNew(requestJSON);
    }

    @Override
    public JSONObject callQueryOwe(JSONObject requestJsonParam) {

        JSONObject requestJSON;
	    requestJSON = EuaCacheUtil.transferParamForConsistence(requestJsonParam);
	    // 入参判空校验
        JSONObject jo = validate(requestJSON);
        if (null != jo) {
            return jo;
        }
        logger.debug("callQueryOwe(账户欠费查询) input :" + requestJSON.toString());
        JSONObject response = null;
        String routeRuleValue = requestJSON.getString("routeRuleValue");
        //-----------1204修改开始
        //11 25 计费重新对接改动
//            String newUrl =BSUrlConstant.U_GET_ACCT_OWE;
        String newUrl = BSSUrlConstants.CON_U_GET_ACCT_OWE;
        //查询账号类型
        String billQueryType = requestJSON.getString("dccDestinationType");
        //查询条件标识
        String destinationAccount = requestJSON.getString("dccDestinationAccount");
        //用户属性
        String destinationAttr = requestJSON.getString("dccDestinationAttr");
        //查询业务类型
        String queryFlag = requestJSON.getString("dccQueryFlag");
        //查询费用类型
        String feeQueryFlag = requestJSON.getString("dccFeeQueryFlag");

        JSONObject paramJson = CreateParamForAccountingCenter.createParamForQryBill(billQueryType, destinationAccount, destinationAttr, queryFlag, feeQueryFlag, routeRuleValue);
        String resultString = HttpClientHelperForEop.postWithMNP(newUrl, paramJson.toJSONString());
        response = HandleParamForAccountingCenter.builderResponseForForQryBillNew(resultString);
        //-----------1204修改结束
        return response;

    }

    @Override
    public JSONObject callUgetBalChg(JSONObject requestJsonParam) {
        JSONObject requestJSON;
	    requestJSON = EuaCacheUtil.transferParamForConsistence(requestJsonParam);
	    // 入参判空校验
        JSONObject jo = validate(requestJSON);
        if (null != jo) {
            return jo;
        }
        logger.debug("callUgetBalChg(余额变动查询) input :" + requestJSON.toString());
        JSONObject response = null;

        //区号
        String routeRuleValue = requestJSON.getString("routeRuleValue");
        //-----------1204修改开始
        //11 25 计费重新对接改动
//            String newUrl =BSUrlConstant.U_GET_EX_BAL;
        String newUrl = BSSUrlConstants.CON_U_GET_EX_BAL;
        String dccAccNbr = requestJSON.getString("dccAccNbr");
        //用户属性 0-固话; 2-移动；  3-宽带
        String dccDestinationAttr = requestJSON.getString("dccDestinationAttr");
        //账期
        String dccBillingCycle = requestJSON.getString("dccBillingCycle");

        //余额类型标识 0：通用余额 1：专用余额 2：用户级 3：用户账目组级 4：账户账目组级
        String balanceTypeFlag = requestJSON.getString("balanceTypeFlag");


        JSONObject paramJson = CreateParamForAccountingCenter.createParamForQryBalanceRecord(dccAccNbr, dccDestinationAttr, dccBillingCycle, routeRuleValue, balanceTypeFlag);
        String resultString = HttpClientHelperForEop.postWithMNP(newUrl, paramJson.toJSONString());
        response = HandleParamForAccountingCenter.builderResponseForQryBalanceRecord(resultString);
        //-----------1204修改结束

        return response;
    }

    @Override
    public JSONObject callUgetBalChgDetail(JSONObject requestJsonParam) {

        JSONObject requestJSON;
	    requestJSON = EuaCacheUtil.transferParamForConsistence(requestJsonParam);
	    
	    // 入参判空校验
        JSONObject jo = validate(requestJSON);
        if (null != jo) {
            return jo;
        }
        logger.debug("callUgetBalChgDetail(余额变动明细查询) input :" + requestJSON.toString());
        JSONObject response = null;
        //区号
        String routeRuleValue = requestJSON.getString("routeRuleValue");
        //-----------1204修改开始
        //11 25 计费重新对接改动
        String newUrl = BSSUrlConstants.CON_U_GET_EX_DET;
        String dccAccNbr = requestJSON.getString("dccAccNbr");
        //用户属性 0-固话; 2-移动；  3-宽带
        String dccDestinationAttr = requestJSON.getString("dccDestinationAttr");
        //账期
        String dccBillingCycle = requestJSON.getString("dccBillingCycle");
        String dataArea = "1";
        JSONObject paramJson = CreateParamForAccountingCenter.createParamForQryPayment(dccAccNbr, dccDestinationAttr, dccBillingCycle, routeRuleValue, dataArea);
        String resultString = HttpClientHelperForEop.postWithMNP(newUrl, paramJson.toJSONString());
        response = HandleParamForAccountingCenter.builderResponseForQryBalanceRecordDetail(resultString);
        //-----------1204修改结束
        return response;

    }

    @Override
    public JSONObject callUgetBalRtn(JSONObject requestJsonParam) {

        JSONObject requestJSON;
	    requestJSON = EuaCacheUtil.transferParamForConsistence(requestJsonParam);
	    // 入参判空校验
        JSONObject jo = validate(requestJSON);
        if (null != jo) {
            return jo;
        }
        logger.debug("callUgetBalRtn(话费返还记录查询) input :" + requestJSON.toString());


        JSONObject response = null;
        //区号
        String routeRuleValue = requestJSON.getString("dccAreaCode");
        //-----------1204修改开始
        //11 25 计费重新对接改动
//            String newUrl =BSUrlConstant.U_GET_BAL_RTN;
        String newUrl = BSSUrlConstants.CON_U_GET_BAL_RTN;
        String dccAccNbr = requestJSON.getString("dccDestinationId");
        //用户属性 0-固话; 2-移动；  3-宽带
        String dccDestinationAttr = requestJSON.getString("dccDestinationAttr");

        String getFlag = MainUtils.getNullEmpty(requestJSON.getString("dccQueryFlag"));
        String dataArea = "";
        //dataArea 1-按账户范围 2-按用户范围 3-按客户范围 按销售品范围
        //getFlag 0：按照合同号查询 1：按用户查询

        if ("0".equals(getFlag)) {
            dataArea = "1";
        } else if ("1".equals(getFlag)) {
            dataArea = "2";
        }

        JSONObject paramJson = CreateParamForAccountingCenter.createParamForBasicStruct(dccAccNbr, dccDestinationAttr, routeRuleValue, dataArea);
        logger.info("callUgetBalRtn 话费返还记录查询入参:{}", paramJson);
        String resultString = HttpClientHelperForEop.postWithMNP(newUrl, paramJson.toJSONString());
        logger.info("callUgetBalRtn 话费返还记录查询 企信出参:{}", resultString);
        response = HandleParamForAccountingCenter.builderResponseForQryReturnBalanceDetail(resultString);
        logger.info("callUgetBalRtn 话费返还记录查询中台出参:{}", response);
        //-----------1204修改结束
        return response;
    }

    @Override
    public JSONObject callUgetBalRtnDetail(JSONObject requestJsonParam) {

        JSONObject requestJSON;
	    requestJSON = EuaCacheUtil.transferParamForConsistence(requestJsonParam);
	    // 入参判空校验
        JSONObject jo = validate(requestJSON);
        if (null != jo) {
            return jo;
        }
        logger.debug("callUgetBalRtnDetail(话费返还记录明细查询) input :" + requestJSON.toString());


        JSONObject response = null;
        //区号
        String routeRuleValue = requestJSON.getString("dccAreaCode");
        //-----------1204修改开始
        //11 25 计费重新对接改动
        String newUrl = BSSUrlConstants.CON_U_GET_BAL_RTN_D;
        String dccAccNbr = requestJSON.getString("dccDestinationId");
        //用户属性 0-固话; 2-移动；  3-宽带
        String dccDestinationAttr = requestJSON.getString("dccDestinationAttr");

        String returnPlanId = requestJSON.getString("dccReturnPlanId");

        //1-按账户范围 2-按用户范围 3-按客户范围 4按销售品范围
        String dataArea = "1";
        JSONObject paramJson = CreateParamForAccountingCenter.createParamForQryReturnBalanceInfoDetail(dccAccNbr, dccDestinationAttr, routeRuleValue, returnPlanId, dataArea);
        logger.info("callUgetBalRtnDetail 话费返还记录明细查询 入参状态:{}", paramJson);
        String resultString = HttpClientHelperForEop.postWithMNP(newUrl, paramJson.toJSONString());
        logger.info("callUgetBalRtnDetail 话费返还记录明细查询 企信出参:{}", resultString);
        response = HandleParamForAccountingCenter.builderResponseForQryReturnBalanceInfoDetail(resultString);
        logger.info("callUgetBalRtnDetail 话费返还记录明细查询 中台出参:{}", response);
        //-----------1204修改结束

        return response;

    }

    @Override
    public JSONObject callUgetPayment(JSONObject requestJsonParam) {

        JSONObject  requestJSON ;
	    requestJSON = EuaCacheUtil.transferParamForConsistence(requestJsonParam);
	    // 入参判空校验
        JSONObject jo = validate(requestJSON);
        if(null != jo) {
            return jo;
        }
        logger.debug("callUgetPayment(缴费充值记录查询) input :" + requestJSON.toString());

        //区号
        String routeRuleValue =  requestJSON.getString("routeRuleValue");
        //-----------1125修改开始
        //11 25 计费重新对接改动
//            String newUrl =BSUrlConstant.U_GET_PAY_BILL;
        String newUrl =BSSUrlConstants.CON_U_GET_PAY_BILL;
        String dccAccNbr  = requestJSON.getString("dccAccNbr");
        //用户属性 0-固话; 2-移动；  3-宽带
        String dccDestinationAttr = requestJSON.getString("dccDestinationAttr");
        //账期
        String dccBillingCycle = requestJSON.getString("dccBillingCycle");
        String dataArea = "1";
        JSONObject paramJson = CreateParamForAccountingCenter.createParamForQryPayment(dccAccNbr, dccDestinationAttr, dccBillingCycle,routeRuleValue,dataArea);
        logger.info("callUgetPayment 缴费充值记录查询 入参:{}", paramJson);

        String resultString = HttpClientHelperForEop.postWithMNP(newUrl, paramJson.toJSONString());
        logger.info("callUgetPayment 缴费充值记录查询 企信出参:{}", resultString);

        return  HandleParamForAccountingCenter.builderResponseForQryPayment(resultString);
        //-----------1125修改结束
    }

    @Override
    public String queryConsistenceNew(String requestJson) {
        logger.debug("queryConsistenceNew:{}",requestJson);
        JSONObject response = null;
        RespInfo responseJson = new RespInfo();
        RespHead responseHead = new RespHead();
        responseJson.setHead(responseHead);
        String tranId = "";
        String getUrl = "";
        String consistenceURL = "http://jsjteop.telecomjs.com:8764/jseop/crm_saop/";

        try {
            JSONObject requestJSON = JSON.parseObject(requestJson);
            JSONObject body = requestJSON.getJSONObject("body");// body
            JSONObject head = requestJSON.getJSONObject("head");// head体
            String lanId = body.getString("lanId");//本地网标识
            String areaCode = "";
            if(StringUtils.isEmpty(lanId)){
                areaCode = head.getString("areaCode");
            }else{
                areaCode = StaticDataMappingUtil.getAreaCodeByRegion(lanId);
            }
            String method = head.getString("method");//调用方法

            getUrl = getUrl(body, head, consistenceURL);

            logger.info("查询企信协议入参：{}",getUrl);
            String result = HttpClientHelperForEop.get(getUrl);
            logger.info("查询企信协议出参：{}",result);

            if(StringUtils.isBlank(result)) {
                response = Utils.builderResponseForFail(responseHead, responseJson, tranId, "01", "查询错误，企信返回空值!");
            }else if("10002".equals(result)){
                response = Utils.builderResponseForFail(responseHead, responseJson, tranId, "02", "Read timed out");
            }else{
                List<JSONArray> listArray = new ArrayList<>();
                List<JSONObject> listObject = new ArrayList<>();
                if(result.subSequence(0, 1).equals("[")){		//数组
                    JSONArray strJSON = JSON.parseArray(result);
                    strJSON =  (JSONArray) dealShortId(strJSON,method,areaCode);
                    listArray.add(strJSON);
                }else{
                    JSONObject strJSON = JSON.parseObject(result);
                    strJSON = (JSONObject) dealShortId(strJSON,method,areaCode);
                    listObject.add(strJSON);
                }

                JSONObject bodyJson = new JSONObject();
                if(!listArray.isEmpty()){
                    bodyJson.put("infoList", listArray);
                }
                if(!listObject.isEmpty()){
                    bodyJson.put("infoList", listObject);
                }

                response = Utils.builderResponseForSuccess(responseHead, responseJson, tranId, bodyJson);
            }
        } catch (Exception e) {
            response = Utils.dealExceptionResp(responseHead, tranId, responseJson);
            logger.debug("queryConsistenceNew Exception:{}",e.getMessage());
        }
        return response.toString();
    }

    private String getUrl(JSONObject body,JSONObject head,String consistenceURL){
        String getUrl = "";
        String accNbr = body.getString("accNbr");// 手机号码
        String number = body.getString("goodsNumber");// 销售品编码
        String lanId = body.getString("lanId");//本地网标识
        String areaCode = head.getString("areaCode");
        if(StringUtils.isEmpty(lanId)&&!StringUtils.isEmpty(areaCode)){
            lanId =  StaticDataMappingUtil.getRegionByAreaCode(areaCode);
        }
        String method = head.getString("method");//调用方法
        String custId = body.getString("custId");//客户id

        if("sQCDescription".equals(method)){
            getUrl = consistenceURL + method+ "/" + method+"?number="+number + "&lanId=" + lanId ;
        }else if("eCProduct".equals(method)){
            if(!StringUtils.isEmpty(custId)){
                getUrl = consistenceURL + method+ "/" + method+"?custId="+custId + "&lanId=" + lanId ;
            }else{
                getUrl = consistenceURL + method+ "/" + method+"?serialNumber="+accNbr + "&lanId=" + lanId ;
            }
        }else if("myProductOffer".equals(method)&& Objects.nonNull(custId)){
            getUrl = consistenceURL + method+ "/" + method+"?custId="+custId + "&lanId=" + lanId ;
        }else{
            getUrl = consistenceURL + method+ "/" + method+"?serialNumber="+accNbr + "&lanId=" + lanId ;
        }
        if(body.containsKey("prodId")){
            getUrl = getUrl +"&type="+body.getString("prodId");
        }
        return getUrl;
    }

    private Object dealShortId(Object object, String method,String areaCode) {
        if ("myProductOffer".equals(method)) {
            if (object instanceof JSONObject) {
                JSONObject newJSONObject = (JSONObject) object;
                String number =  newJSONObject.getString("number");
                newJSONObject.put("oriNumber", number);
                if(number.length()>=16){//长编码
                    number =  getShortId(number,areaCode);
                    newJSONObject.put("number",number);
                }
                return newJSONObject;
            } else if (object instanceof JSONArray) {
                JSONArray newJSONArray = (JSONArray) object;
                if(newJSONArray.size()>0){
                    for(int i =0;i<newJSONArray.size();i++){
                        String number =  newJSONArray.getJSONObject(i).getString("number");
                        newJSONArray.getJSONObject(i).put("oriNumber", number);
                        if(number.length()>=16){//长编码
                            number =  getShortId(number,areaCode);
                            newJSONArray.getJSONObject(i).put("number",number);
                        }
                    }
                }
                return newJSONArray;
            }
            return null;
        } else {
            return object;
        }
    }

    private String getShortId(String number,String areaCode){
        String shortId = redisOperation.getForString("getShortId2_"+number);
        if(StringUtils.isEmpty(shortId)){
            String requestStr ="{    'body': {      'offerNbr':'"+number+"' ,'statusCds':['1000','1400','1500']  },    'head': {        'actionCode': '195531',        'areaCode':'"+areaCode+"',        'auth': '4e3026d15126c391973ff2fe97a3f4e3',        'channelId': 'WT',        'loginNbr': '025202377714',        'loginType': '2000004',        'requestTime': '2018-06-29 11:18:49',        'tranId': '20180629111849000000'    }}";
            String responseStr = bssSystemImpl.qryOfferSpecDetail(requestStr);
            JSONObject responseBody = JSONObject.parseObject(responseStr);
            JSONObject head = responseBody.getJSONObject("head");
            if("00".equals(head.getString("status"))){
                JSONObject body = responseBody.getJSONObject("body");
                String offerId = body.getJSONObject("resultObject").getString("offerId");
                if(!StringUtils.isEmpty(offerId)){
                    redisOperation.setForString("getShortId2_"+number, offerId);
                    return offerId;
                }
            }
            return null;
        }else{
            return shortId;
        }
    }

    /**
     * 请求入参参数校验
     * @param requestJSON 入参
     * @return response 参数校验结果
     * */
    public JSONObject validate(JSONObject requestJSON) {
        JSONObject response = null;
        if(null == requestJSON) {
            response = new JSONObject();
            response.put("errorCode", ExpConstant.ERROR_INPUT_NULL);
            response.put("errorMsg", "request params is null,plc check.");
            response.put("success", "OK");
            response.put("bodys", "");
        }
        return response;
    }

    /**
     * 异常结果返回处理
     */
    public JSONObject dealExceptionResp(String responseStr, String exceptionMsg) {
        JSONObject response = new JSONObject();
        response.put("errorCode", ExpConstant.ERROR_INNER_EXCEPTION); // 接口异常，内部异常+SGW接口调用异常
        response.put("errorMsg", exceptionMsg); // 接口异常描述
        response.put("success", "");
        response.put("bodys", responseStr);
        return response;
    }
}
